/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package onpu_dms_xls.kernel.common.pdf.composite;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import onpu_dms_xls.kernel.common.Util;
import onpu_dms_xls.kernel.common.logAndDebug.LoggingFacade;
import onpu_dms_xls.kernel.common.vipiska.Extract_Subject;
import org.apache.log4j.Logger;

/**
 *
 * @author snbm
 */
public class ExtractMarkLabels extends ExtractLabel {
    

    private List<Extract_Subject> subjects = new ArrayList<Extract_Subject>();
    private int firstNameColLeftBorder;
    private int firstNameColRightBorder;
    private int firstColFirstLineY;
    private int firstColSecondLineY;
    private int secondAndThirdColFirstLineY;
    private int secondAndThirdColSecondLineY;
    private int bottomY;
    private int studyHourX;
    private int markX;
    private double rowHeigh;
    private int columnDelta;

    public ExtractMarkLabels(String n) {
        super(n);
        LoggingFacade.trace.trace("PDF_MarkLabels constructor n=" + n);
    }

    @Override
    public void printToPDFWriter(PDF_ExtractWriter pdf_ew) {
//        pdf_ew.addTask(new PDF_ExtractWriterTask(this, this.getPageNum(), dataToPrintGetter));
        //for marks.

        final double MARKS_ONE_CHAR_SIZE = Util.get_ONE_CHAR_SIZE(this);
        int currentX = getFirstNameColLeftBorder();
        double currentY = getFirstColFirstLineY();
        int currentLeftBorder = getFirstNameColLeftBorder();
        int currentRightBorder = getFirstNameColRightBorder();
        int columnIndex = 1;

        for (Extract_Subject subj : getSubjects()) {
            ArrayList<String> words = Util.getWordsFromString(subj.getFullName());
            int hours = subj.getHours();
            String mark = String.valueOf(subj.getMark());

            int lineLehgthInChars = (int) ((currentRightBorder - currentLeftBorder) / MARKS_ONE_CHAR_SIZE);

            boolean canWriteAndNoEndReached = checkForEndInMarksColumns(currentY, this, words, lineLehgthInChars, columnIndex);

            if (canWriteAndNoEndReached) {

                //hours
                pdf_ew.addTask(new PDF_ExtractWriterTask(getPageNum(), getFont(), getCodePage(), getFontSize(), String.valueOf(hours), getStudyHourX() + getColumnDelta() * (columnIndex - 1), (int) (currentY) - 2));
                //mark
                pdf_ew.addTask(new PDF_ExtractWriterTask(getPageNum(), getFont(), getCodePage(), getFontSize(), mark, getMarkX() + getColumnDelta() * (columnIndex - 1), (int) (currentY) - 3));

                int wordIndex = 0;
                int lineIndex = 1;

                LoggingFacade.trace.debug("mark line for " + subj.getFullName());

                while (true) {
                    if (lineIndex % 2 == 1) {
                        //1,3,5 lines
                        StringBuilder oddLine = new StringBuilder();
                        while (true) {
                            if (wordIndex == words.size()) {
                                //для однолинейных предметов - вывожу немного ниже, с эстетической точки зрения
                                //но только для однолинейных.
                                if (lineIndex == 1) { //эта проверка, не лишняя, ибо тут может закончиться предмет 3 линейный
                                    pdf_ew.addTask(new PDF_ExtractWriterTask(getPageNum(), getFont(), getCodePage(), getFontSize(), oddLine.toString(), currentX, (int) (currentY) - 3));
                                } else {
                                    pdf_ew.addTask(new PDF_ExtractWriterTask(getPageNum(), getFont(), getCodePage(), getFontSize(), oddLine.toString(), currentX, (int) (currentY)));
                                }
                                break;
                            }
                            if ((oddLine.length() + words.get(wordIndex).length()) > lineLehgthInChars) {
                                pdf_ew.addTask(new PDF_ExtractWriterTask(getPageNum(), getFont(), getCodePage(), getFontSize(), oddLine.toString(), currentX, (int) (currentY)));
                                break;
                            }
                            oddLine.append(words.get(wordIndex));
                            wordIndex++;
                        }
                        if (wordIndex == words.size()) {
                            currentY -= getRowHeigh();
                            break;
                        } else {
                            lineIndex++;
                            if (columnIndex == 1) {
                                currentY -= (getFirstColFirstLineY() - getFirstColSecondLineY());
                            } else {
                                currentY -= (getSecondAndThirdColFirstLineY() - getSecondAndThirdColSecondLineY());
                            }
                        }
                    } else {
                        //2,4,6 lines
                        StringBuilder evenLine = new StringBuilder();
                        while (true) {
                            if (wordIndex == words.size()) {
                                pdf_ew.addTask(new PDF_ExtractWriterTask(getPageNum(), getFont(), getCodePage(), getFontSize(), evenLine.toString(), currentX, (int) (currentY)));
                                break;
                            }
                            if ((evenLine.length() + words.get(wordIndex).length()) > lineLehgthInChars) {
                                pdf_ew.addTask(new PDF_ExtractWriterTask(getPageNum(), getFont(), getCodePage(), getFontSize(), evenLine.toString(), currentX, (int) (currentY)));
                                break;
                            }
                            evenLine.append(words.get(wordIndex));
                            wordIndex++;
                        }
                        if (wordIndex == words.size()) {
                            if (columnIndex == 1) {
                                currentY -= (getFirstColSecondLineY() - (getFirstColFirstLineY() - getRowHeigh()));
                            } else {
                                currentY -= (getSecondAndThirdColSecondLineY() - (getSecondAndThirdColFirstLineY() - getRowHeigh()));
                            }
                            break;
                        } else {
                            lineIndex++;
                            if (columnIndex == 1) {
                                currentY -= (getFirstColSecondLineY() - (getFirstColFirstLineY() - getRowHeigh()));
                            } else {
                                currentY -= (getSecondAndThirdColSecondLineY() - (getSecondAndThirdColFirstLineY() - getRowHeigh()));
                            }
                        }
                    }
                }
            } else {
                LoggingFacade.trace.info("END OF COLUMN REACHED");
                //установка параметров, чтобы следующие предметы выводились в следующей колонке
                if (columnIndex == 1) {
                    //goto second column
                    currentX = getFirstNameColLeftBorder() + getColumnDelta();
                    currentY = getSecondAndThirdColFirstLineY();
                    currentLeftBorder = getFirstNameColLeftBorder() + getColumnDelta();
                    currentRightBorder = getFirstNameColRightBorder() + getColumnDelta();
                    columnIndex = 2;
                } else if (columnIndex == 2) {
                    //goto third column
                    currentX = getFirstNameColLeftBorder() + getColumnDelta() * 2;
                    currentY = getSecondAndThirdColFirstLineY();
                    currentLeftBorder = getFirstNameColLeftBorder() + getColumnDelta() * 2;
                    currentRightBorder = getFirstNameColRightBorder() + getColumnDelta() * 2;
                    columnIndex = 3;
                } else if (columnIndex == 3) {
                    throw new RuntimeException("end of third column. Change your font size :-)");
                }
            }
        }
        return;
    }


    /**
    !!!!!!!!!!!! three lines only!!!!!!!!!!!!!
     */
    private boolean checkForEndInMarksColumns(
            double currentY,
            ExtractMarkLabels markLabels,
            ArrayList<String> words,
            int lineLehgthInChars,
            int columnIndex) {

        int wordIndex = 0;
        int lineIndex = 1;

        while (true) {
            if (lineIndex % 2 == 1) {
                //1,3,5 lines
                StringBuilder oddLine = new StringBuilder();
                while (true) {
                    if (wordIndex == words.size()) {
                        break;
                    }
                    if ((oddLine.length() + words.get(wordIndex).length()) > lineLehgthInChars) {
                        break;
                    }
                    oddLine.append(words.get(wordIndex));
                    wordIndex++;
                }
                if (wordIndex == words.size()) {
                    currentY -= markLabels.getRowHeigh();
                    break;
                } else {
                    lineIndex++;
                    if (columnIndex == 1) {
                        currentY -= (markLabels.getFirstColFirstLineY() - markLabels.getFirstColSecondLineY());
                    } else {
                        currentY -= (markLabels.getSecondAndThirdColFirstLineY() - markLabels.getSecondAndThirdColSecondLineY());
                    }
                }
            } else {
                //2,4,6 lines
                StringBuilder evenLine = new StringBuilder();
                while (true) {
                    if (wordIndex == words.size()) {
                        break;
                    }
                    if ((evenLine.length() + words.get(wordIndex).length()) > lineLehgthInChars) {
                        break;
                    }
                    evenLine.append(words.get(wordIndex));
                    wordIndex++;
                }
                if (wordIndex == words.size()) {
                    if (columnIndex == 1) {
                        currentY -= (markLabels.getFirstColSecondLineY() - (markLabels.getFirstColFirstLineY() - markLabels.getRowHeigh()));
                    } else {
                        currentY -= (markLabels.getSecondAndThirdColSecondLineY() - (markLabels.getSecondAndThirdColFirstLineY() - markLabels.getRowHeigh()));
                    }
                    break;
                } else {
                    lineIndex++;
                    if (columnIndex == 1) {
                        currentY -= (markLabels.getFirstColSecondLineY() - (markLabels.getFirstColFirstLineY() - markLabels.getRowHeigh()));
                    } else {
                        currentY -= (markLabels.getSecondAndThirdColSecondLineY() - (markLabels.getSecondAndThirdColFirstLineY() - markLabels.getRowHeigh()));
                    }
                }
            }
        }


        return (currentY > markLabels.getBottomY());
    }


    @Override
    public void print() {
        LoggingFacade.trace.debug("PDF_MarkLabels print, variableName = " + getVariableName());
    }

    @Override
    public Iterator<ExtractComponent> getIterator() {
        return (new ArrayList<ExtractComponent>()).iterator();
    }

    /***
    НЕ ИСПОЛЬЗОВАТЬ!, у оценок нету одного getY
     */
    @Override
    public int getY() {
        return -1;
    }

    /**
     * @return the subjects
     */
    public List<Extract_Subject> getSubjects() {
        return subjects;
    }

    /**
     * @param subjects the subjects to set
     */
    public void setSubjects(ArrayList<Extract_Subject> subjects) {
        this.subjects = subjects;
    }

    /**
     * @return the firstNameColLeftBorder
     */
    public int getFirstNameColLeftBorder() {
        return firstNameColLeftBorder;
    }

    /**
     * @param firstNameColLeftBorder the firstNameColLeftBorder to set
     */
    public void setFirstNameColLeftBorder(int firstNameColLeftBorder) {
        this.firstNameColLeftBorder = firstNameColLeftBorder;
    }

    /**
     * @return the firstNameColRightBorder
     */
    public int getFirstNameColRightBorder() {
        return firstNameColRightBorder;
    }

    /**
     * @param firstNameColRightBorder the firstNameColRightBorder to set
     */
    public void setFirstNameColRightBorder(int firstNameColRightBorder) {
        this.firstNameColRightBorder = firstNameColRightBorder;
    }

    /**
     * @return the studyHourX
     */
    public int getStudyHourX() {
        return studyHourX;
    }

    /**
     * @param studyHourX the studyHourX to set
     */
    public void setStudyHourX(int studyHourX) {
        this.studyHourX = studyHourX;
    }

    /**
     * @return the markX
     */
    public int getMarkX() {
        return markX;
    }

    /**
     * @param markX the markX to set
     */
    public void setMarkX(int markX) {
        this.markX = markX;
    }

    /**
     * @return the rowHeigh
     */
    public double getRowHeigh() {
        return rowHeigh;
    }

    /**
     * @param rowHeigh the rowHeigh to set
     */
    public void setRowHeigh(double rowHeigh) {
        this.rowHeigh = rowHeigh;
    }

    /**
     * @return the columnDelta
     */
    public int getColumnDelta() {
        return columnDelta;
    }

    /**
     * @param columnDelta the columnDelta to set
     */
    public void setColumnDelta(int columnDelta) {
        this.columnDelta = columnDelta;
    }

    /**
     * @return the firstColFirstLineY
     */
    public int getFirstColFirstLineY() {
        return firstColFirstLineY;
    }

    /**
     * @param firstColFirstLineY the firstColFirstLineY to set
     */
    public void setFirstColFirstLineY(int firstColFirstLineY) {
        this.firstColFirstLineY = firstColFirstLineY;
    }

    /**
     * @return the firstColSecondLineY
     */
    public int getFirstColSecondLineY() {
        return firstColSecondLineY;
    }

    /**
     * @param firstColSecondLineY the firstColSecondLineY to set
     */
    public void setFirstColSecondLineY(int firstColSecondLineY) {
        this.firstColSecondLineY = firstColSecondLineY;
    }

    /**
     * @return the secondAndThirdColFirstLineY
     */
    public int getSecondAndThirdColFirstLineY() {
        return secondAndThirdColFirstLineY;
    }

    /**
     * @param secondAndThirdColFirstLineY the secondAndThirdColFirstLineY to set
     */
    public void setSecondAndThirdColFirstLineY(int secondAndThirdColFirstLineY) {
        this.secondAndThirdColFirstLineY = secondAndThirdColFirstLineY;
    }

    /**
     * @return the secondAndThirdColSecondLineY
     */
    public int getSecondAndThirdColSecondLineY() {
        return secondAndThirdColSecondLineY;
    }

    /**
     * @param secondAndThirdColSecondLineY the secondAndThirdColSecondLineY to set
     */
    public void setSecondAndThirdColSecondLineY(int secondAndThirdColSecondLineY) {
        this.secondAndThirdColSecondLineY = secondAndThirdColSecondLineY;
    }

    /**
     * @return the bottomY
     */
    public int getBottomY() {
        return bottomY;
    }

    /**
     * @param bottomY the bottomY to set
     */
    public void setBottomY(int bottomY) {
        this.bottomY = bottomY;
    }
}
